<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/9/6
 * Time: 14:27
 */

namespace app\api\service;


use app\lib\enum\OrderStatusEnum;
use app\lib\exception\OrderException;
use app\lib\exception\TokenException;
use think\Exception;
use app\api\model\Order as orderModel;
use think\Loader;
use think\Log;

//引用微信支付类
Loader::import('WxPay.WxPay',EXTEND_PATH,'.Api.php');
class Pay
{
    private $orderId;
    private $orderNo;

    public function __construct($orderId)
    {
        if (!$orderId){
            throw new Exception('订单号不能为null');
        }
        $this->orderId = $orderId;
    }

    public function pay()
    {
        //1.订单号可能不存在
        //2.订单号确实存在的,但是,订单号和当前用户是否匹配
        //3.订单有可能已经支付过
        $this->checkOrderValid();
        //4.进行库存量检测
        $orderService = new Order();
        $status = $orderService->checkOrderStock($this->orderId);
        if ($status['pass']){
            return $status;
        }

        //先调用该接口在微信支付服务后台生成预支付交易单，返回正确的预支付交易后调起支付
        return $this->makeWxPreOrder($status['orderPrice']);
    }

    //发送预订单请求
    private function makeWxPreOrder($totalPrice)
    {
        //获取帐号的openid
        $openid = ToToken::getCurrentTokenVar('openid');
        if (!$openid){
            throw new TokenException();
        }
        //调用微信支付jdk
        $wxOrderData = new \WxPayUnifiedOrder();//统一下订单
        $wxOrderData->SetOut_trade_no($this->orderNo);
        $wxOrderData->SetTrade_type('JSAPI');
        $wxOrderData->SetTotal_fee($totalPrice*100);
        $wxOrderData->SetBody('零食商贩');
        $wxOrderData->SetOpenid($openid);
        $wxOrderData->SetNotify_url(config('secure.pay_back_url'));//回调地址

        return $this->getPaySignature($wxOrderData);
    }

    private function getPaySignature($wxOrderData){
         $wxOrder = \WxPayApi::unifiedOrder($wxOrderData);
         if ($wxOrder['return_code'] != 'SUCCESS' ||
                $wxOrder['result_code'] != 'SUCCESS'
         ){
             Log::record($wxOrder,'error');
             Log::record('获取预支付订单失败','error');
         }
         //prepay_id
        $this->recordPreOrder($wxOrder);
        $signature = $this->sign($wxOrder);
        return $signature;
    }

    //签名
    private function sign($wxOrder){
        $jsApiPayData = NEW \WxPayJsApiPay();
        $jsApiPayData->SetAppid(config('wx.app_id'));
        $jsApiPayData->SetTimeStamp((string)time());
        $rand = md5(time().mt_rand(0,1000));
        $jsApiPayData->SetNonceStr($rand);
        $jsApiPayData->SetPackage('prepay_id='.$wxOrder['prepay_id']);
        $jsApiPayData->SetSignType('md5');
        $sign = $jsApiPayData->MakeSign();
        $rawValues = $jsApiPayData->GetValues();
        $rawValues['paySign'] = $sign;

        unset($rawValues['appId']);
        return $rawValues;
    }

    //存储微信返回的prepay_id
    private function recordPreOrder($wxOrder){
        orderModel::where('id','=',$this->orderId)
            ->update(['prepay_id'=>$wxOrder['prepay_id']]);
    }

    //查询订单是否存在
    private function checkOrderValid()
    {
        $order = orderModel::where('id','=',$this->orderId)
            ->find();
        if (!$order){
            throw new OrderException();
        }
        if (!ToToken::isValidOperate($order->user_id)){
            throw new TokenException([
               'msg'=>'订单与用户不匹配',
               'errorCode'=>'100003',
            ]);
        }
        if ($order->status != OrderStatusEnum::UNPAID)
        {
            throw new OrderException([
                'msg'=>'订单状态异常',
                'errorCode'=>80003,
                'code'=>400,
            ]);
        }
        $this->orderNo = $order->order_no;
        return true;
    }
}